﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using Noea.HTTP;

namespace Noea.HTTP
{
    public class HTTPTCPClient : IHTTP
    {
        private TcpClient tcpClient;
        private string address = "127.0.0.1";
        private int port = 80;
        private int timeout = 1000;
        //private NotifyLog notify;

        /// <summary>
        /// Gets a value indicating whether a Socket is connected to a remote host.
        /// </summary>
        /// <value>true if the socket is connected, otherwise false</value>>
        public bool IsConnected()
        {
            return tcpClient.Connected;
        }

        /// <summary>
        /// Gets or sets the timeout value for sending and receiving. 
        /// If the the timeout value is exceeded an exception should be thrown
        /// </summary>
        /// <value>The timeout period in millisecs</value>
        public int TimeOut
        {
            get { return tcpClient.SendTimeout; }
            set { tcpClient.SendTimeout = tcpClient.ReceiveTimeout = value; }

        }

        /// <summary>
        /// Opens the connection to the server.
        /// Pre:	The server can be reached by the url and portnumber
        /// Post:	Connection etablished
        /// </summary>
        /// <param name="url">Identification of the server. i.e a dns name or a ip address</param>
        /// <param name="port">Number between 1 and 65335, default 80</param>
        public void Open(string url, int port)
        {
            this.address = url;
            this.port = port;
            
            tcpClient = new TcpClient(this.GetHost(url), port);
        }

        private string GetHost(string link)
        {
            return new Uri(link).Host;
        }

        private String GetUrl(string link)
        {
            return new Uri(link).LocalPath;
        }

        /// <summary>
        /// Closes the connection to server. 
        /// </summary>
        public void Close()
        {
            GetStream().Close();
            tcpClient.Close();
        }

        /// <summary>
        /// Sends a request to the server, i.e by using http
        /// Pre:	A connection is established to the server
        /// Post:	A request is sent to the server
        /// </summary>
        /// <param name="command">the request, i.e "GET /index.html"</param>
        public void SendRequest()
        {
            string cmd = "GET " + this.GetUrl(this.address) + " HTTP/1.1\r\nHost: " + this.GetHost(this.address) + "\r\nConnection: Close\r\n\r\n";
            byte[] cmdBytes = Encoding.ASCII.GetBytes(cmd);
            GetStream().Write(cmdBytes, 0, cmdBytes.Length);
        }

        /// <summary>
        /// Receives the response from the server
        /// Pre:	A request has been sent to the server, and IsConnected is still true
        /// Post:	The response is returned in a string
        /// </summary>
        /// <returns>the response from the server</returns>
        public string Receive()
        {
            byte[] respondBuffer = new byte[tcpClient.ReceiveBufferSize + 1];
            int length = GetStream().Read(respondBuffer, 0, tcpClient.ReceiveBufferSize);
            string data = Encoding.ASCII.GetString(respondBuffer);
            char[] unused = {(char)data[length]};
            return data.TrimEnd(unused);
        }

        /// <summary>
        /// Gets a stream object to the server object, that might be used for common stream operations.
        /// Pre:	A connection is etablished to the server
        /// Post:	A stream object is returned, i.e a NetworkStream object.
        /// </summary>
        /// <returns>a stream object</returns>
        public System.IO.Stream GetStream()
        {
            return tcpClient.GetStream();
        }
    }
}


